package com.sjs.boot.dynamic.facade;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author uto_dev_008
 * @desc
 * @since 2021/11/9 17:43
 * Copyright (c) 2021 南京友拓信息技术有限公司 All rights reserved
 */
abstract public class AbstractInitializer {
    private Logger LOG = LoggerFactory.getLogger(AbstractInitializer.class);
    private AppInitializer appInitializer = null; //针对不同应用的初始化工作，比如web、console等不同的应用

    /**
     * 在数据库配置之后，其他配置初始化之前调用
     *
     * @param configPath
     * @return
     */
    abstract protected int beforeInit(String configPath);

    /**
     * 在所有初始成功之后
     *
     * @param configPath
     * @return
     */
    abstract protected int afterInit(String configPath);

    /**
     * 可以重装此函数，用于销毁beforeInit/afterInit时初始化的资源
     */
    abstract protected void destroy();

    /**
     * 获取日志对象，一定要在init中调用的抽象函数中，或者之后才可以调用
     *
     * @return
     */
    protected Logger getLOG() {
        return LOG;
    }

    /**
     * 做所有的初始化工作
     *
     * @param configPath
     * @return
     */
    public int init(String configPath) {
        try {
            int retCode = beforeInit(configPath);
            if (retCode != 0) {
                LOG.error("Fail to call beforeInit, retCode {}", retCode);
                return retCode;
            }
            if (appInitializer != null) {
                if ((retCode = appInitializer.init(configPath)) != 0) {
                    LOG.error("Fail to call appInitializer.init,result:{}", retCode);
                    return retCode;
                }
            }
            retCode = afterInit(configPath);
            if (retCode != 0) {
                LOG.error("Fail to call afterInit, retCode {}", retCode);
                return retCode;
            }
        } catch (Exception e) {
            LOG.error("Fail to load config", e);
            return 100;
        }
        return 0;
    }

    public void destroyed() {
        if (appInitializer != null) {
            appInitializer.destroy();
        }
        destroy();
        getLOG().info("=== System destroyed ===");
    }

    public void setAppInitializer(AppInitializer appInitializer) {
        this.appInitializer = appInitializer;
    }

    public static interface AppInitializer {
        public int init(String configPath);

        public void destroy();
    }
}
